package com.hk.Mgr.web.controller.app;

import java.net.URI;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

import com.google.gson.Gson;
import com.hk.commons.ResultCode;
import com.hk.commons.entity.EncourageHistory;
import com.hk.commons.entity.Parameter;
import com.hk.commons.entity.order.OrderInfo;
import com.hk.commons.entity.sys.SysUser;
import com.hk.service.IEncourageHistory;
import com.hk.service.message.CouponResult;
import com.hk.service.order.impl.OrderHandleContent;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hk.Mgr.web.message.StatusCode;
import com.hk.base.BaseCtrl;
import com.hk.base.ResponseBase;
import com.hk.commons.ConstantCard;
import com.hk.commons.entity.product.ProductInfo;
import com.hk.commons.vo.CheckInfo;
import com.hk.commons.vo.UserCardMsg;
import com.hk.commons.vo.UserCardReqMsg;
import com.hk.service.kyc.ICoupon;
import com.hk.service.order.IParameter;
import com.hk.service.product.IProductInfo;
import com.hk.service.sys.ISysUser;

/**
 * 用户积分
 * 
 * @author jeff
 *
 */
@Controller
@RequestMapping(value = BaseCtrl.App + "/couponCtr")
public class AppCouponCtrl extends BaseCtrl {

	@Autowired
	private ISysUser userService;
	
	@Autowired
	private IProductInfo prodService;

	@Autowired
	private ICoupon  couponService;
	
	@Autowired
	private IParameter parmService;

	@Autowired
	private ISysUser sysUserService;

	@Autowired
	private IEncourageHistory encourageHistoryService;

	@Autowired
	private JdbcTemplate jdbcTemplate;

	@Autowired
	private OrderHandleContent orderContent;

	@Value("${msgserver.baseUrl}")
	private String msgServerHost;

	private static boolean isHandle = false;

	private static Object lock = new Object();

	private static final String JH_ACTIVITY_BEGIN = "JH_ACTIVITY_BEGIN";
	private static final String JH_ACTIVITY_END = "JH_ACTIVITY_END";

	/**
	 * 领取加息券
	 * 
	 * @param
	 * @return
	 */
	@RequestMapping(value = "/getCard", method = RequestMethod.POST)
	@ResponseBody
	public ResponseBase<Boolean> getCard(@RequestBody UserCardReqMsg  req) {
		
		ResponseBase<Boolean> resp = new ResponseBase<Boolean>();
		
		Long userId = req.getUserId();
		
		Long cardId = req.getCardId();
		
		logger.info("getCard userId={}, userCardId={}",userId, cardId);
		
		if (userId == null || cardId == null || userService.existById(userId) == false) {
			resp.setMsg("参数错误");
			resp.setResultCode(StatusCode.PARAM_ERROR.key());
			return resp;
		}

		CheckInfo checkInfo = couponService.sendCoupon(userId, cardId);
		
		logger.info("getCard result: userId={}, userCardId={}, result={}",userId, cardId, checkInfo.getResult()); 
		
		resp.setResult(checkInfo.getResult());
		
		resp.setResultCode(StatusCode.SUCCESS.key());
		return resp;
	}

	/**
	 * 获取卡券列表
	 * 
	 * @param
	 * @return
	 */
	@RequestMapping(value = "/list", method = RequestMethod.POST)
	@ResponseBody
	public ResponseBase<List<UserCardMsg>> list(@RequestBody UserCardReqMsg req) {
		
		ResponseBase<List<UserCardMsg>> resp = new ResponseBase<List<UserCardMsg>>();
		
		List<UserCardMsg> cardResList = new ArrayList<UserCardMsg>();
		
		Long userId = req.getUserId();
		
		Integer status = req.getStatus();
		
		Long productId = req.getProductId();
		
		logger.info("getCard list parm: userId={}, status={}, productId={}",userId, req.getStatus(), productId);
		
		if (userId == null || userService.existById(userId) == false) {
			resp.setMsg("参数错误");
			resp.setResultCode(StatusCode.PARAM_ERROR.key());
			return resp;
		}

		//限制销户用户-2.7.6
		SysUser user = sysUserService.findById(userId);
		if(user == null || user.getCloseAccount() == 1){
			resp.setResult(null);
			resp.setResultCode(ResultCode.USER_NOT_EXIST.getCode());
			resp.setMsg(ResultCode.USER_NOT_EXIST.getMsg());
			return resp;
		}



		DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd kk:mm:ss");

		Parameter jhActivityBegin = this.parmService.getByName(JH_ACTIVITY_BEGIN);
		Parameter jhActivityEnd = this.parmService.getByName(JH_ACTIVITY_END);

		LocalDateTime localNow = LocalDateTime.now();

		LocalDateTime activityBegin = LocalDateTime.parse(jhActivityBegin.getValue01(), dateTimeFormatter);
		LocalDateTime activityEnd = LocalDateTime.parse(jhActivityEnd.getValue01(), dateTimeFormatter);

		if (localNow.compareTo(activityBegin) > 0 && localNow.compareTo(activityEnd) < 0) {
			try {
				if (req.getStatus() == 0) {
					synchronized (lock) {
						if (!isHandle) {
							isHandle = true;
							LocalDate today = LocalDate.now();
							long now = System.currentTimeMillis();

							List<Long> idList = this.encourageHistoryService.findAllOrderId();
							List<Map<String, Object>> orderList;

							String productSql = "select id from t_product_info where label01 = '京华专标'";
							List<Map<String, Object>> productIdList = this.jdbcTemplate.queryForList(productSql);
							StringBuilder productSB = new StringBuilder();
							productSB.append("(");
							for (Map<String, Object> productID: productIdList) {
								productSB.append(productID.get("id") + ",");
							}
							productSB = new StringBuilder(productSB.substring(0, productSB.length()-1));
							productSB.append(")");

							if (idList.size() > 0) {
								StringBuilder sb = new StringBuilder();
								sb.append("(");
								for (Long id: idList) {
									sb.append(id + ",");
								}
								sb = new StringBuilder(sb.substring(0, sb.length()-1));
								sb.append(")");

								String orderSql = String.format("select id from t_order_info where orderCreatedOn >= ? and orderCreatedOn < ? and productId in %s and id not in %s", productSB.toString(), sb.toString());
								orderList = this.jdbcTemplate.queryForList(orderSql, new Object[] {
										Timestamp.valueOf(LocalDateTime.of(today, LocalTime.of(0, 0))).getTime(),
										now
								});
							} else {
								String orderSql = String.format("select id from t_order_info where orderCreatedOn >= ? and orderCreatedOn < ? and productId in %s", productSB.toString());
								orderList = this.jdbcTemplate.queryForList(orderSql, new Object[] {
										Timestamp.valueOf(LocalDateTime.of(today, LocalTime.of(0, 0))).getTime(),
										now
								});
							}

							for (Map<String, Object> order: orderList) {
								Long orderId = (Long)order.get("id");

								EncourageHistory encourageHistory = new EncourageHistory();
								encourageHistory.setOrderId(orderId);
								this.encourageHistoryService.add(encourageHistory);

								OrderInfo orderInfo = this.orderContent.findByOrderId(orderId);
								CouponResult threeEndResult = this.orderContent.checkThreeEndUser(orderInfo, orderInfo.getProductId());
								CouponResult oneDayResult = this.orderContent.checkOneDayEncourage(orderInfo, orderInfo.getProductId());
								CouponResult threeComboResult = this.orderContent.checkThreeComboEncourage(orderInfo, orderInfo.getProductId());

								logger.info("order id: " + orderId);
								logger.info("three result: " + threeEndResult);
								logger.info("one day result: " + oneDayResult);
								logger.info("three combo result: " + threeComboResult);


								if ( (threeEndResult.getFlag() && threeEndResult.getCount()) ||
										(oneDayResult.getFlag() && oneDayResult.getCount()) ||
										(threeComboResult.getCouponCount().intValue() != 0 && threeComboResult.getCouponCount().intValue() % 3 == 0 && threeComboResult.getCount())) {
									ExecutorService executor = Executors.newFixedThreadPool(1);
									Runnable task = new Runnable() {
										public void run() {
											try {
												String tokenUrl = String.format("%s/getToken", AppCouponCtrl.this.msgServerHost);
												URI uri = new URI(tokenUrl);
												HttpGet httpGet = new HttpGet(uri);
												HttpClient httpClient = HttpClients.createDefault();
												HttpResponse response = httpClient.execute(httpGet);
												int statusCode = response.getStatusLine().getStatusCode();

												if(statusCode == HttpStatus.SC_OK){
													String body = EntityUtils.toString(response.getEntity());
													Gson gson = new Gson();
													ResponseBase responseBase = gson.fromJson(body, ResponseBase.class);
													String token = (String)responseBase.getResult();

													SysUser sysUser = AppCouponCtrl.this.sysUserService.findById(orderInfo.getUserId());

													String url = String.format("%s/sendMsg?content=%s&mobile=%s&token=%s",
															AppCouponCtrl.this.msgServerHost,
															"您已满足“投资满额送京东卡”活动条件，打开华财通“我的-我的优惠”即可查看专属礼品",
															sysUser.getName(),
															token);
													httpGet = new HttpGet(url);
													httpClient = HttpClients.createDefault();
													response = httpClient.execute(httpGet);
													statusCode = response.getStatusLine().getStatusCode();

													if (statusCode == HttpStatus.SC_OK) {
														body = EntityUtils.toString(response.getEntity());
														logger.info("msg server: " + body);
													}
												}
											} catch (Exception e) {
												logger.error("send message error: ", e);
											}
										}
									};
									executor.execute(task);
									executor.shutdown();
								}
							}
							isHandle = false;
						}
					}
				}
			} catch (Exception e) {
				logger.error("can be ignore", e);
			}
		}

		if("2".equals(req.getChannel())){
			cardResList = couponService.getCouponList(userId, status);
			//cardResList = cardResList.stream().map(card ->card.getCardType()==1 || card.getCardType()==5).collect(Collectors.toList());
			cardResList = cardResList
                    .stream()
                    .filter(card -> card.getCardType()==1 || card.getCardType()==5)
                    .collect(Collectors.toList());
		} else if(productId == null){
			cardResList = couponService.getCouponList(userId, status);
		}else if(req.getAmount() == null){
			ProductInfo prod = prodService.findById(productId);
			if(prod == null || prod.getSaleType() == null ){
				resp.setMsg("产品不存在或产品优惠类型错误");
				resp.setResultCode(StatusCode.PARAM_ERROR.key());
				return resp;
			}
			cardResList =  couponService.getCouponList(userId, req.getStatus(), prod.getId());
		}else{
			cardResList = couponService.getCouponList(userId,req.getStatus(),productId,req.getAmount(),req.getCardStatus());
		}
		
		int size = 0;
		
		if(cardResList != null){
			size = cardResList.size();
		}
		
		resp.setSize(size);
		resp.setResult(cardResList);
		resp.setResultCode(StatusCode.SUCCESS.key());
		return resp;
	}
	
	/**
	 * 获取卡券描述信息
	 * 
	 * @param
	 * @return
	 */
	@RequestMapping(value = "/getInfoById", method = RequestMethod.POST)
	@ResponseBody
	public ResponseBase<UserCardMsg> getInfoById(@RequestBody UserCardReqMsg req) {
		
		ResponseBase<UserCardMsg> resp = new ResponseBase<UserCardMsg>();
		
		 UserCardMsg  userCardMsg = new UserCardMsg();
		
		Long userId = req.getUserId();
		
		Long userCardId = req.getUserCardId();
		
		if (userId == null || userCardId == null || userService.existById(userId) == false) {
			resp.setMsg("参数错误");
			resp.setResultCode(StatusCode.PARAM_ERROR.key());
			return resp;
		}
		
		userCardMsg = couponService.getCouponInfo(userId, userCardId);
		
		if(userCardMsg != null){
			resp.setResult(userCardMsg);
			resp.setResultCode(StatusCode.SUCCESS.key());
		}else{
			resp.setResultCode(StatusCode.ERROR.key());
			resp.setMsg("读取卡券信息错误");
		}
		
		return resp;
	}
}
